package com.shijie.judgeBox;

import com.shijie.constant.JudgeExConstant;
import com.shijie.entity.Submit.CodeType;
import com.shijie.exception.JudgeException;
import com.shijie.judgeBox.annotation.JudgeCodeType;
import com.shijie.utlis.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@RequiredArgsConstructor
public class JudgeWorkerCreator {

    private final ApplicationContext applicationContext;

    private static ConcurrentHashMap<String, JudgeWorker> beansMap;

    public JudgeWorker createJudgeWorker(CodeType codeType) {
        if (beansMap == null)
            beansMap = new ConcurrentHashMap<>();
        if (beansMap.isEmpty())
            beansMap.putAll(applicationContext.getBeansOfType(JudgeWorker.class));

        JudgeWorker bean = null;
        for (JudgeWorker v : beansMap.values())
            // JudgeWorkerCodeType.value() 默认值 CodeType.Java
            if (v.getClass().getAnnotation(JudgeCodeType.class).value().equals(codeType)) {
                bean = v;
                break;
            }

        if (bean == null)
            log.error("该类型的Bean未找到，可能未定义该程序语言及判题实现类或未添加程序语言标识注解");

        return bean;
    }


    public interface JudgeWorker {

        @Deprecated
        String OutDirPrefix = "judges/";

        /**
         * 统一的返回接口
         *
         * @param code       String
         * @param codeType   Submit.CodeType
         * @param paramsType Class<?>[]
         * @param params     List< List<?>>
         * @param resultType Class<?>
         * @param results    List< List<?>>
         * @return Integer[] index-0：耗时ms，index-1：内存kb
         */
        Integer[] working(String code, CodeType codeType,
                          Class<?>[] paramsType, List<List<?>> params,
                          Class<?> resultType, List<List<?>> results);


        /**
         * 比较结果接口
         *
         * @param resultType Class< ?>
         * @param originRs   List< List<?>>
         * @param targetRs   List< List<?>>
         */
        static void compare(Class<?> resultType, List<List<?>> originRs, List<List<?>> targetRs) {
            Object origin = null;
            Object target = null;

            for (int i = 0; i < originRs.size(); i++) {
                origin = JsonUtils.argvCast(originRs.get(i).getFirst(), resultType);
                target = JsonUtils.argvCast(targetRs.get(i).getFirst(), resultType);

                // 数组类型的比较不同，使用Objects.deepEquals()都能比较
                if (!Objects.deepEquals(origin, target))
                    throw new JudgeException(JudgeExConstant.COMPARE_FAULT);
            }
        }

    }


}
